package com.okaixz.client.utils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Base64;

/**
 * AES-256加密解密工具类
 * 支持GCM模式，提供安全的加密解密功能
 */
public class AES256Util {
    
    // AES-GCM参数
    private static final String ALGORITHM = "AES";
    private static final String TRANSFORMATION = "AES/GCM/NoPadding";
    private static final int GCM_IV_LENGTH = 12; // IV长度为12字节
    private static final int GCM_TAG_LENGTH = 16; // Tag长度为16字节
    private static final String key1="LcrYuQyFSJdeKSgXHwDgr27xzNJ8wr/x9UMkS3oNE7w=";
    private static final String key2="LcrYuQyFSJdeKSgXHwDgr99xzNJ8wr/x9UMkS3oNE8w=";//保存数据库用的key

    /**
     * 生成AES-256密钥
     * @return Base64编码的密钥字符串
     * @throws Exception 异常
     */
    public static String generateKey() throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
        keyGenerator.init(256);
        SecretKey key = keyGenerator.generateKey();
        return Base64.getEncoder().encodeToString(key.getEncoded());
    }
    
    /**
     * 加密数据
     * @param data 待加密的数据
     * @param keyBase64 Base64编码的密钥
     * @return 加密后的数据(Base64编码)，格式为 IV + 密文
     * @throws Exception 异常
     */
    public static String encrypt(String data, String keyBase64) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(keyBase64);
        SecretKey key = new SecretKeySpec(keyBytes, ALGORITHM);
        
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        
        // 生成随机IV
        byte[] iv = new byte[GCM_IV_LENGTH];
        new SecureRandom().nextBytes(iv);
        
        GCMParameterSpec parameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv);
        cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
        
        byte[] encryptedData = cipher.doFinal(data.getBytes());
        
        // 将IV和密文合并
        byte[] combined = new byte[iv.length + encryptedData.length];
        System.arraycopy(iv, 0, combined, 0, iv.length);
        System.arraycopy(encryptedData, 0, combined, iv.length, encryptedData.length);
        
        return Base64.getEncoder().encodeToString(combined);
    }
    
    /**
     * 解密数据
     * @param encryptedDataBase64 加密的数据(Base64编码)，格式为 IV + 密文
     * @param keyBase64 Base64编码的密钥
     * @return 解密后的原始数据
     * @throws Exception 异常
     */
    public static String decrypt(String encryptedDataBase64, String keyBase64) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(keyBase64);
        SecretKey key = new SecretKeySpec(keyBytes, ALGORITHM);
        
        byte[] combined = Base64.getDecoder().decode(encryptedDataBase64);
        
        // 分离IV和密文
        byte[] iv = new byte[GCM_IV_LENGTH];
        byte[] encryptedData = new byte[combined.length - GCM_IV_LENGTH];
        System.arraycopy(combined, 0, iv, 0, iv.length);
        System.arraycopy(combined, iv.length, encryptedData, 0, encryptedData.length);
        
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        GCMParameterSpec parameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, iv);
        cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec);
        
        byte[] decryptedData = cipher.doFinal(encryptedData);
        return new String(decryptedData);
    }
    
    /**
     * 示例用法
     */
    public static void main(String[] args) {
        try {
            // 生成密钥
            System.out.println("生成的密钥: " + key2);
            
            // 待加密数据
            String originalData = "012549";
            System.out.println("原始数据: " + originalData);
            
            // 加密
            String encryptedData = encrypt(originalData, key2);
            System.out.println("加密后数据: " + encryptedData);
            
            // 解密
            String decryptedData = decrypt(encryptedData, key2);
            System.out.println("解密后数据: " + decryptedData);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String encryptDb(String originalData){
        try {
            return encrypt(originalData, key2);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    public static String decryptDb(String encryptedData){
        try {
            return decrypt(encryptedData, key2);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    public static String encryptUser(String originalData,String salt){
        try {
            return encrypt(originalData+salt, key1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    public static String decryptUser(String encryptedData,String salt){
        try {
            return decrypt(encryptedData, key1).replace(salt,"");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
